//
//  GCDSocketManager.m
//  DriverBus
//
//  Created by MacMini20170218 on 2017/3/27.
//  Copyright © 2017年 JiYang. All rights reserved.
//

#import "GCDSocketManager.h"
#import "BusStop.h"
#import <AVFoundation/AVFoundation.h>

#define SocketHost @"122.114.61.173"  //地址
#define SocketPort 8282 //端口

@implementation GCDSocketManager{
    AppDelegate *appDelegate;
    AVSpeechSynthesizer *av;
    NSUserDefaults *userDefaults;
    BOOL cutSocket;
}

//全局访问点
+ (instancetype)sharedSocketManager{
    static GCDSocketManager *_instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [[self alloc]init];
    });
    return _instance;
}

//可以在这里做你想要的一些初始化操作
- (instancetype)init{
    self = [super init];
    if(self){
        appDelegate = (AppDelegate*)[[UIApplication sharedApplication]delegate];
        av = [[AVSpeechSynthesizer alloc]init];
        //不自动锁屏
        [UIApplication sharedApplication].idleTimerDisabled = YES;
        //
        userDefaults = [NSUserDefaults standardUserDefaults];
    }
    return self;
}

#pragma mark 请求连接
- (void)connectToSocket{
    cutSocket = NO;
    //初始化socket
    self.socket = [[GCDAsyncSocket alloc]initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
    //连接失败的错误
    NSError *error = nil;
    //开始连接
    [self.socket connectToHost:SocketHost onPort:SocketPort error:&error];
    //如果连接失败，打印错误
    if(error){
        NSLog(@"sokcet connect error:%@",error);
    }
}

#pragma mark 如果连接成功
//连接成功回调
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port{
    if(cutSocket){
        return;
    }
    //如果连接成功，向服务器发送数据
    //发送数据
    NSString* s = [NSString stringWithFormat:@"{\"action\":\"login\",\"id\":\"%@\",\"group\":\"driver\",\"password\":\"%@\"}",appDelegate.driver.account,appDelegate.driver.pass];
    [self sendDataToServer:s];
    //启动心跳
    self.timerHeart = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(sendHeart) userInfo:nil repeats:YES];
    [self.timerHeart fire];
}

- (void)sendDataToServer:(NSString*)dataString{
    //发送数据
    NSData *jsonData = [dataString dataUsingEncoding:NSUTF8StringEncoding];
    //以下两句代码必须写，少一句数据就不会发送、读取成功
    [self.socket writeData:jsonData withTimeout:-1 tag:1];
    //读取数据
    [self.socket readDataWithTimeout:-1 tag:200];
}

- (void)sendHeart{
    NSLog(@"SEND HEART");
    // 向服务器发送固定的消息，来检测长连接
    NSString *hearBeat = @"{\"action\":\"heartbeat\"}";
    NSData   *data  = [hearBeat dataUsingEncoding:NSUTF8StringEncoding];
    [self.socket writeData:data withTimeout:3 tag:2];
    [self.socket readDataWithTimeout:30 tag:202];
}

/*
 timeout，超时时间。根据实际需求去设置，我这里设置为-1。
 
 tag：发送数据和读取数据的tag值一定不能设置成一样的。
 为什么不能设置成一样的呢？举个例子。
 在这里tag相当于一个通道，并且在这个通道中只能完成一件事情。
 如果这个通道专门用来发送数据的，就给这个通道打个标签，标签值就是1吧。
 如果这个通道专门用来读取数据的，就给这个通道打个标签，标签纸就是200把。
 数值随便定义，只能你能确保两者的tag值不一样。
 */
#pragma mark 接收到数据
//连接成功向服务器发数据后，服务器会有响应
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
    //这句代码必须写
    [self.socket readDataWithTimeout:-1 tag:200];
    //
    NSString *str = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
    //拆分数据
    NSArray *array = [str componentsSeparatedByString:@"}"];
    NSMutableArray *mArray = [[NSMutableArray alloc]initWithArray:array];
    [mArray removeObject:@""];
    for(int i=0;i<mArray.count;i++){
        NSMutableString *mstr = [[NSMutableString alloc]initWithString:[mArray objectAtIndex:i]];
        [mstr appendString:@"}"];
        NSString* string = [[NSString alloc]initWithString:mstr];
        [mArray setObject:string atIndexedSubscript:i];
        NSData *mData = [string dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
        NSError *mError;
        NSDictionary *mDict = [NSJSONSerialization JSONObjectWithData:mData options:NSJSONReadingMutableLeaves error:&mError];
        if(mError){
            NSLog(@"解析报错-%@",mError);
        }
        NSString *action = [mDict objectForKey:@"action"];
        NSString *status =[mDict objectForKey:@"status"];
        NSLog(@"status:%@",status);
        //NSString *detail = [mDict objectForKey:@"detail"];
        if([action isEqualToString:@"login"]){
            if([status isEqualToString:@"success"]){
                appDelegate.hasConnectServer = YES;
            }
        }
        if([action isEqualToString:@"call"]){
            NSString *directionS = [mDict objectForKey:@"direction"];
            NSInteger direction = [directionS integerValue];
            //呼叫方向不同，不播报
            if(direction!=appDelegate.direction){
                return;
            }
            NSString *stopId = [mDict objectForKey:@"location"];
            BusStop *stop = [appDelegate.busStopsDictionary objectForKey:stopId];
            NSString *callString = [NSString stringWithFormat:@"%@乘客呼叫",stop.name];
            //如果是在后台，则发送本地通知
            if([[userDefaults objectForKey:@"appStatu"] isEqualToString:@"back"]){
                [MyNotification sendNotification:@"乘客呼叫" content:callString];
                return;
            }
            AVSpeechSynthesisVoice *voice = [AVSpeechSynthesisVoice voiceWithLanguage:@"zh_CN"];
            AVSpeechUtterance *utterance = [[AVSpeechUtterance alloc]initWithString:callString];
            utterance.rate=0.5;// 设置语速，范围0-1，注意0最慢，1最快
            utterance.voice = voice;
            [av speakUtterance:utterance];
        }else if([action isEqualToString:@"message"]){
            NSString *content = [mDict objectForKey:@"content"];
            //如果是在后台，则发送本地通知
            if([[userDefaults objectForKey:@"appStatu"] isEqualToString:@"back"]){
                [MyNotification sendNotification:@"后勤消息" content:content];
                return;
            }
            AVSpeechSynthesisVoice *voice = [AVSpeechSynthesisVoice voiceWithLanguage:@"zh_CN"];
            AVSpeechUtterance *utterance = [[AVSpeechUtterance alloc]initWithString:content];
            utterance.rate=0.5;// 设置语速，范围0-1，注意0最慢，1最快
            utterance.voice = voice;
            [av speakUtterance:utterance];
        }
    }
}

#pragma mark 连接失败
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err{
    NSLog(@"Socket连接失败");
    [self reconnectServer];
}

- (void)reconnectServer{
    if(cutSocket){
        return;
    }
    NSError *error = nil;
    [self.socket connectToHost:SocketHost onPort:SocketPort error:&error];
    if(error){
        NSLog(@"socket reconnect error:%@",error);
    }
}

#pragma mark 断开重连

- (void)cutOffSocket{
    NSLog(@"断开socket连接");
    cutSocket = YES;
    if([self.timerHeart isValid]){
        
        [self.timerHeart invalidate];
        self.timerHeart = nil;
    }
    [self.socket disconnect];
}

@end
